images - animated applications

revision:


Content

image carousels object tag rotate images random picture generator photo galleries thumbnails

image carousels

top

carousel of cars

code:
        <div class="spec">
            <main id="carousel-container">
                <ul id="carousel-1">
                <li class="slide-1" id="audi"><img src="../images/car1.jpg" alt="Audi"/> </li>
                <li class="slide-1" id="ferrari"><img src="../images/car2.jpg" alt="Ferrari" /></li>
                <li class="slide-1" id="lamborghini"><img src="../images/car3.jpg" alt="Lamborghini" /></li>
                <li class="slide-1" id="bmw"><img src="../images/car4.jpg" alt="BMW" /></li>
                <li class="slide-1" id="mercedes"><img src="../images/car5.jpg" alt="Mercedes" /></li>
                </ul>
            </main>
            <nav>
                <a href="#audi">Audi</a>
                <a href="#ferrari">Ferrari</a>
                <a href="#lamborghini">Lamborghini</a>
                <a href="#bmw">BMW</a>
                <a href="#mercedes">Mercedes</a>
            </nav>
        </div>
        <style>
        #carousel-container {height: 40vw; width: 50vw; padding: 0; overflow-x: scroll; scroll-snap-type: x mandatory; scroll-behavior: smooth; --slide-count: 5;margin: 0 auto; }
        #carousel-1 { width: calc(100% * var(--slide-count)); display: flex; }
        #carousel, .slide {height: 100%; list-style: none; margin: 0; padding: 0;}
        .slide-1 {scroll-snap-align: start;}
        .slide-1 > img {width: 100%; height: 100%; object-fit: cover;}
        a { display: inline-block; margin: 0.25vw;}
        nav {text-align: center; }
        </style>
    

another carousel of cars

code:
        <main id="carousel-container-2">
            <ul id="carousel-2">
            <li class="slide-2" id="audi-2"><img src="../images/car1.jpg" alt="Audi"/> </li>
            <li class="slide-2" id="ferrari-2"><img src="../images/car2.jpg" alt="Ferrari" /></li>
            <li class="slide-2" id="lamborghini-2"><img src="../images/car3.jpg" alt="Lamborghini" /></li>
            <li class="slide-2" id="bmw-2"><img src="../images/car4.jpg" alt="BMW" /></li>
            <li class="slide-2" id="mercedes-2"><img src="../images/car5.jpg" alt="Mercedes" /></li>
            </ul>
        </main>
        <nav id="nv-2">
            <a href="#audi-2">Audi</a>
            <a href="#ferrari-2">Ferrari</a>
            <a href="#lamborghini-2">Lamborghini</a>
            <a href="#bmw-2">BMW</a>
            <a href="#mercedes-2">Mercedes</a>
        </nav>
        <style>
            #carousel-container-2 {height: 40vw; width: 50vw; padding: 0; overflow: hidden; margin: 0 auto;}
            #carousel-2 {position: relative;}
            #carousel-2, .slide-2 {height: 100%;list-style: none; margin: 0; padding: 0;}
            .slide-2 { width: 100%;  position: absolute; left: 0;  top: 0;  opacity: 0; transition: opacity 300ms; }
            .slide-2 > img { width: 100%; height: 100%; object-fit: cover;}
            .slide-2:first-child, .slide-2:target { opacity: 1; }
            .nv-2 a {display: inline-block; margin: 2vw; }
            .nv-2 {text-align: center;}
        </style>  
    

another carousel of cars

code:
        <main id="carousel-container-3">
            <ul id="carousel-3">
            <li class="slide-3" id="audi-3"><img src="../images/car1.jpg" alt="Audi"/> </li>
            <li class="slide-3" id="ferrari-3"><img src="../images/car2.jpg" alt="Ferrari" /></li>
            <li class="slide-3" id="lamborghini-3"><img src="../images/car3.jpg" alt="Lamborghini" /></li>
            <li class="slide-3" id="bmw-3"><img src="../images/car4.jpg" alt="BMW" /></li>
            <li class="slide-3" id="mercedes-3"><img src="../images/car5.jpg" alt="Mercedes" /></li>
            </ul>
        </main>
        <nav id="nv-3">
            <a href="#audi-3">Audi</a>
            <a href="#ferrari-3">Ferrari</a>
            <a href="#lamborghini-3">Lamborghini</a>
            <a href="#bmw-3">BMW</a>
            <a href="#mercedes-3">Mercedes</a>
        </nav>  
        <style>
            #carousel-container-3 {height: 40vw; width: 50vw; padding: 0; margin: 0 auto;}
            #carousel-3 {position: relative;}
            #carousel-3, .slide-3 {height: 100%; list-style: none; margin: 0; padding: 0;}
            .slide-3 { width: 100%; position: absolute; left: 0; top: 0; opacity: 0; transform: scale(0.5) rotate(-10deg); filter: 
                blur(2vw) brightness(0); transition: opacity 1s, transform 1s, filter 1s; pointer-events: none;}
            .slide-3 > img {width: 100%; height: 100%;  object-fit: cover;}
            .slide-3:target { opacity: 1;  transform: scale(1) rotate(0); filter: blur(0) brightness(1);}
            .slide-3:target ~ .slide-3 { opacity: 0;  transform: scale(1.5) rotate(10deg); filter: blur(20px) brightness(2); }
            .nv-3 a {display: inline-block; margin: 2vw; }
            .nv-3 {text-align: center; }
        </style>
    


object tag

top

insert video in webpage

code:
        <div>
            <object class="example-1" width="500" height="350" title="Wuzhen" style="margin-left:20vw;">
                <param name="movie-1" value="Wuzhen-20-10_9091.mp4">
                <param name="quality-1" value="high"> 
                <embed src="../images/Wuzhen-20-10_01.mp4" quality="high" type="video/mp4" width="500" 
                height="350"></embed>
            </object>
        </div>
    

insert image in webpage

code:
        <object class="example-2" width="500" height="350" title="holidays" style="margin-left: 20vw;">
            <param name="image-2" value="2.jpg">
            <param name="quality-2" value="high"> 
            <embed src="2.jpg" quality="high" type="image/jpg" width="500" height="350"></embed>
        </object>
    

insert media files (e.g. gif files) in webpage

Sorry!,Your browser does not support
code:
        <div class="example-3"class="flex-container" style="margin-left: 20vw;">
            <object height="250" width="500" data="../images/gif1.gif"></object>  
            <object height="250" width="500" data="../images/gif2.gif"></object>  
            <object height="250" width="500" data="../images/gif3.gif"></object>  
            <object height="250" width="500" data="../images/ducks.gif">Sorry!,
            Your browser does not support</object>  
        </div>         
    

insert PDF file in webpage

You don't have a PDF plugin, but you can download the PDF file.

code:
        <object class="example-4" data="../images/blog-20-12-13.pdf" type="application/pdf" width="500" height="300" style="margin-left: 20vw;"  typemustmatch> </object>
        <p>You don't have a PDF plugin, but you can <a href="../images/blog-20-12-13.pdf"> download the PDF file.
        </a></p>
    


rotate images

top

method 1: using JS - getElementById()

Click on the image to rotate it 180 degrees clockwise.

cartoon

method 2: using JS - getElementById()/CSS

Click on the image to rotate it 90 degrees clockwise.

cartoon
code:
        <div class="grid_A">
            <div>
                <h3>method 1: using JS - getElementById()</h3>
                <p class="spec">Click on the image to rotate it 180 degrees clockwise.</p>
                <img src="../images/cartoon.jpg" id="image1" onclick="rotateImage();" alt="cartoon" />
            </div>
            <div>
                <h3>method 2: using JS - getElementById()/CSS</h3>
                <p class="spec">Click on the image to rotate it 90 degrees clockwise.</p>
                <img src="../images/cartoon.jpg" id="image2" onclick="rotate();" alt="cartoon" />
            </div>
        </div>
        <style>
            #image1{margin-left: 3vw; width: 15vw; height: 15vw;}
            #image2{margin-left: 3vw; width: 15vw; height: 15vw;}
            .element {transform: rotate(90deg);}
        </style>
        <script>
            function rotateImage() {
                var img = document.getElementById('image1');
                img.style.transform = 'rotate(180deg)';
            }
        
            function rotate() {
                var img = document.getElementById('image2');
                img.className = 'element';
            }
        </script>
    

method 3: rotate using butten (onclick)

Click on the button to rotate it 90 degrees anti-clockwise.

cartoon

method 4: rotate using button (onclick)

Click on the button to rotate it 90 degrees sequentially (clockwise).

cartoon
code:
        <div class="grid_A">
            <div>
                <h3>method 3: rotate using butten (onclick)</h3>
                <p class="spec">Click on the button to rotate it 90 degrees anti-clockwise.</p>
                <img src="../images/cartoon.jpg" id="image3" alt="cartoon" />
                <button onClick="rotateImg() ">rotate image</button>
            </div>   
            <div>
                <h3>method 4: rotate using button (onclick)</h3>
                <p class="spec">Click on the button to rotate it 90 degrees sequentially (clockwise).</p>
                <img src="../images/cartoon.jpg" id="image4" alt="cartoon" />
                <button onClick="rotateImg2()">rotate image</button>
            </div>
        </div>
        <style>
            #image3{margin-left: 3vw; width: 15vw; height: 15vw;} 
            #image4{margin-left: 3vw; width: 15vw; height: 15vw;}
        </style>  
        <script>
            function rotateImg() {
                document.querySelector("#image3").style.transform = "rotate(-90deg)";
            }
        
            let rotation = 0;
            function rotateImg2() {
                rotation += 90; // add 90 degrees
                if (rotation === 360) { 
                    // 360 means rotate back to 0
                    rotation = 0;
                }
                document.querySelector("#image4").style.transform = `rotate(${rotation}deg)`;
            }
        </script>
    

method 5: rotate using button (i.e. using id attribute)

Click on the button to rotate it 90 degrees sequentially (anti-clockwise).

method 6: rotate by clicking the image (using setAttribute)

code:
            <div class="grid_A">
                <div class="spec">
                    <h3>method 5: rotate using button (i.e. using id attribute)</h3>
                    <p class="spec">Click on the button to rotate it 90 degrees sequentially (anti-clockwise).</p>
                    <img id="sample" src="../images/cartoon.jpg" />
                    <button id="rotate-button">rotate image</button>
                </div>
                <div>
                    <h3>method 6: rotate by clicking the image (using setAttribute)</h3>
                    <img id="image5" src="../images/cartoon.jpg" onclick="turn();"/>
                </div>
            </div>
            <style>
                #sample{margin-left: 3vw; width: 15vw; height: 15vw;}
                #image5{margin-left: 3vw; width: 15vw; height: 15vw;}
            </style>   
            <script>
                var current_rotation = 0;
                // change CSS transform property on click
                document.querySelector("#rotate-button").addEventListener('click', function() {
                    // update total rotation
                    // if angle is positive, rotation happens clockwise. if negative, rotation happens anti-clockwise.
                    current_rotation -= 90;
                    // rotate clockwise by 90 degrees
                    document.querySelector("#sample").style.transform = 'rotate(' + current_rotation + 'deg)';
                });
        
                function turn(){ 
                    var img=document.getElementById('image5'); 
                    img.setAttribute('style','transform:rotate(180deg)'); 
                } 
            </script>
        


random picture generator

top
code:
 
        <div class="spec">
            <button id="but1">generate random picture</button>
            <section class="flex"><img id="picture" src=""></section>
        </div>
        <style>
            .flex {display: flex; margin: 0 auto; justify-content: center; align-items: center; width: 30vw; height:30vw; border:0.5vw inset burlywood;}
            #but1{width: 5vw; margin-left:10vw; border:0.25vw solid green; color: black;}
            .flex img { width: 30vw; height: 30vw;margin-left:-.5vw;}
        </style>
        <script>
            const imageArray = ["../images/1a.jpg" , "../images/2a.jpg", "../images/3a.jpg", "../images/4a.jpg", "../images/5a.jpg" , "../images/6a.jpg", "../images/7a.jpg"];
            const image = document.querySelector("#picture");
            const button = document.querySelector("#but1");
            window.onload = () => generateRandomPicture(imageArray);
            button.addEventListener("click", () => generateRandomPicture(imageArray));
            function generateRandomPicture(array){
                let randomNum = Math.floor(Math.random() * array.length); 
                image.setAttribute("src", imageArray[randomNum]);
            }
        </script>
    


photo galleries

top

photo gallery 1

code:
        <div id="mainContainer" class="spec">
            <div id="thumbnails">
                <img class="imgThumbnails" src="2.jpg"/>
                <img class="imgThumbnails" src="3.jpg"/>
                <img class="imgThumbnails" src="4.jpg" />
                <img class="imgThumbnails" src="5.jpg" />
                <img class="imgThumbnails" src="6.jpg" />
                <img class="imgThumbnails" src="19.jpg" />
                <img class="imgThumbnails" src="20.jpg" />
                <img class="imgThumbnails" src="1.jpg" />
            </div>
                <div id="mainImage"><img src="1.jpg" /></div>
                <div id="imgCaption"></div>
        </div>
        <style>
        #mainContainer {width: 40vw; height: 40vw; top: 0;}
        #mainImage {margin: 1vw; height: 20vw;}
        #mainImage img {margin-left: 1vw;  width: 35vw;  height: 30vw; border: 1vw outset burlywood;}
        #thumbnails {display: flex; flex-flow: row nowrap; padding-top: 0.2vw; width: 6vw; height: 6vw;}
        .imgThumbnails {margin-left: 0.5vw;height: 5vw; width: 5vw; margin-bottom: 0vw;}
        .imgThumbnails:hover {cursor: pointer;}
        </style>
        <script>
            (function start(){
            let mainImage = document.getElementById("mainImage").getElementsByTagName("img")[0],
                thumbnailImages = document.getElementById("thumbnails").getElementsByTagName("img"),
                j = 0;  
            let startTimer = function(){
                stillTimer = setInterval(function(){
                        j = (j < 7) ? ++j : 0 ;
                        mainImage.src = thumbnailImages[j].src;
                    }, 10000);
                }   
            startTimer();
            for(i = 0 ; i < thumbnailImages.length ; i++){
                thumbnailImages[i].addEventListener("click", function(evt){     
                    clearInterval(stillTimer);
                    mainImage.src = evt.target.src;                 
                    ++j; 
                    startTimer();
                });
            };
            })();
        </script>
    

photo gallery 2

code:
        <div class="spec">
            <div class="gallery-photos clearfix">
                <div class="photo-thumbnails">
                    <div class="thumbnail current"><div class="thumbnail-inner">
                    <img src="../images/1.jpg" alt="" /></div></div>
                    <div class="thumbnail"><div class="thumbnail-inner">
                    <img src="../images/2.jpg" alt="" /></div></div>
                    <div class="thumbnail"><div class="thumbnail-inner">
                    <img src="../images/3.jpg" alt="" /></div></div>
                    <div class="thumbnail"><div class="thumbnail-inner">
                    <img src="../images/4.jpg" alt="" /></div></div>
                    <div class="thumbnail"><div class="thumbnail-inner">
                    <img src="../images/5.jpg" alt="" /></div></div>
                    <div class="thumbnail"><div class="thumbnail-inner">
                    <img src="../images/6.jpg" alt="" /></div></div>
                    <div class="thumbnail"><div class="thumbnail-inner">
                    <img src="../images/8.jpg" alt="" /></div></div>
                    <div class="thumbnail"><div class="thumbnail-inner">
                    <img src="../images/9.jpg" alt="" /></div></div>
                </div>
                <div id="big-photo" class="big-photo">
                <img src="../images/1.jpg" alt="" /> </div>
            </div>
        </div>
        <style>
                .gallery-photos {padding: 1vw; width: 40vw; height:40vw; margin: 0 auto;}
                .gallery-photos .big-photo {display: flex; padding: 0.3vw;  border: 1vw solid burlywood; margin-right: 1vw; width: 35vw; height: 30vw;}
                .gallery-photos .big-photo img {display: inline-flex; width: 35vw; height: 30vw; justify-content:left; border: inset 1vw solid burlywood;}
                .gallery-photos .photo-thumbnails {display: inline-flex; flex-flow:row nowrap ; width: auto;}
                .gallery-photos .photo-thumbnails .thumbnail {float: left; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; width: 5vw; height: 5vw; 
                    cursor: pointer; padding: 0.1vw; border: 0.1vw solid skyblue; margin-left: 3.33333%; margin-bottom: 6px; opacity: 0.6; }
                .gallery-photos .photo-thumbnails .thumbnail.current {opacity: 1; background-color: green;}
                .gallery-photos .photo-thumbnails .thumbnail .thumbnail-inner { height: 100%; overflow: hidden;}
                .gallery-photos .photo-thumbnails .thumbnail img { display: block; width: auto; max-height: 100%;
                        margin: 0 auto;}
        </style>
        <script>
            $(document).ready(function(){
                $(".photo-thumbnails .thumbnail").click(function() {
                    $('.photo-thumbnail .thumbnail').removeClass('current');
                    $(this).addClass('current');
                    var path = $(this).find('img').attr('src');
                    $('#big-photo img').attr('src', path);
                });
            })
        </script>
    

responsive gallery: examples

code:
        <section class="gallery">
            <h4>Gallery title here</h4>
            <div>
                <img src="../images/17.jpg" alt="">
                <img src="../images/18.jpg" alt="">
                <img src="../images/19.jpg" alt="">
                <img src="../images/20.jpg" alt="">
                <img src="../images/21.jpg" alt="">
                <img src="../images/22.jpg" alt="">
                <img src="../images/23.jpg" alt="">
                <img src="../images/24.jpg" alt="">
                <img src="../images/25.jpg" alt="">
            </div>
        </section>
        <style>
            .gallery > div {columns:5;  gap:1vw; padding-top:1.25vw; }
            .gallery img { display:block; width:100%; margin-bottom:1.25vw; }
            @media (max-width:48vw) {
                .gallery > div { columns:2;}
            }
            @media (max-width:32vw) {
            .gallery > div { columns:1;}
            }
        </style>
    

different photo-gallery formats

Default format

Horizontal layout format

Square layout format

Customized Gap

Gap between images with value of 1vw

Row Height and Column Width

Row height with value of 10vw and column width with value of 15vw

code:
        <div class="gg-container">
            <h3>Default format</h3>
            <div class="gg-box">
                <img src="../images/1.jpg">
                <img src="../images/1a.jpg">
                <img src="../images/1S.jpg">
                <img src="../images/2.jpg">
                <img src="../images/2a.jpg">
                <img src="../images/2S.jpg">
                <img src="../images/3.jpg">
                <img src="../images/3a.jpg">
                <img src="../images/3aa.jpg">
                <img src="../images/3s.jpg">
                <img src="../images/4.jpg">
                <img src="../images/4a.jpg">
                <img src="../images/4aa.jpg">
                <img src="../images/4s.jpg">
            </div>
            <h3>Horizontal layout format</h3>
            <div class="gg-box dark" id="horizontal">
                <img src="../images/7a.jpg">
                <img src="../images/7aa.jpg">
                <img src="../images/8.jpg">
                <img src="../images/8a.jpg">
                <img src="../images/9.jpg">
                <img src="../images/9a.jpg">
            </div>
            <h3>Square layout format</h3>
            <div class="gg-box dark" id="square">
                <img src="../images/9.jpg">
                <img src="../images/9a.jpg">
                <img src="../images/10.jpg">
                <img src="../images/10a.jpg">
                <img src="../images/11.jpg">
                <img src="../images/11a.jpg">
                <img src="../images/12.jpg">
                <img src="../images/12a.jpg">
            </div>
            <h3>Customized Gap</h3>
            <p>Gap between images with value of 1vw</p>
            <div class="gg-box" id="gap">
                <img src="../images/13a.jpg">
                <img src="../images/14a.jpg">
                <img src="../images/17.jpg">
                <img src="../images/18.jpg">
                <img src="../images/19.jpg">
                <img src="../images/20.jpg">
            </div>
            <h3>Row Height and Column Width</h3>
            <p>Row height with value of 10vw and column width with value of 15vw</p>
            <div class="gg-box dark" id="heightWidth">
                <img src="../images/21.jpg">
                <img src="../images/22.jpg">
                <img src="../images/23.jpg">
                <img src="../images/24.jpg">
                <img src="../images/25.jpg">
                <img src="../images/26.jpg">
            </div>
        </div>
        <style>
            .gg-container { --main-color: #000; --secondary-color: #111; --txt-color: #fff; --img-bg-color: rgba(240, 240, 240, 0.9); --backdrop-color: rgba(240, 240, 240, 0.9); --gap-length: 2px; --row-height: 200px; 
                --column-width: 220px;}
            .gg-container *[data-theme="dark"] { --main-color: #ddd; --secondary-color: #eee; --txt-color: #111; --img-bg-color: rgba(20, 20, 20, 0.9);  --backdrop-color: rgba(30, 30, 30, 0.9); }
            .gg-box {display: grid; grid-template-columns: repeat(auto-fit, minmax(var(--column-width), 1fr)); grid-auto-rows: var(--row-height); grid-gap: var(--gap-length);  margin: 1vw 0; }
            .gg-box img {object-fit: cover; cursor: pointer; width: 100%; height: 100%; background: var(--img-bg-color);}
            .gg-box img:hover {opacity: 0.98;}
            #gap{gap: 1vw;}
            .gg-box .dark{width: 15vw; height: 10vw;}
            #gg-screen { position: fixed; width: 100%; height: 100%;  top: 0; left: 0; background: var(--backdrop-color); z-index: 9999;  text-align: center; }
            #gg-screen .gg-image {height: 100%; display: inline-flex; justify-content: center; align-items: center;}
            #gg-screen .gg-image img {max-width: 100%; max-height: 100%; margin: 0 auto;}
            .gg-btn {width: 35px; height: 35px; background: var(--main-color); color: var(--txt-color); text-align: center; line-height: 35px;  cursor: pointer; -moz-transition: all 0.4s ease; -o-transition: all 0.4s ease; 
                -webkit-transition: all 0.4s ease;  transition: all 0.4s ease; font-size: 20px; box-sizing: border-box;  padding-left: 2px;  position: fixed;
            bottom: 10px;}
            .gg-btn:hover { background: var(--secondary-color); }
            .gg-close {top: 10px;}
            .gg-close, .gg-next { right: 10px;}
            .gg-prev {right: 50px;}
            .gg-prev,.gg-next {bottom: 10px;}
            @media (min-width: 478px) {
                .gg-box img:nth-child(2n):not(:last-of-type) {grid-row-end: span 2;}
                [data-layout="horizontal"] img:nth-child(2n):not(:last-of-type) {grid-column-end: span 2; grid-row-end: span 1;}
                [data-layout="square"] img:nth-child(2n):not(:last-of-type) {grid-row-end: span 1;grid-column-end: span 1;}
            }
            @media (max-width: 768px) {
                .gg-box {grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); grid-auto-rows: calc(var(--row-height) - 15vh); margin: 10px 0;}
            }
            @media (max-width: 450px) {
                .gg-box {grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));}
            }
        </style>
        <script>
            const root = document.querySelector("body, html");
            const container = document.querySelector('.gg-container');
            const images = document.querySelectorAll(".gg-box > img");
            const l = images.length;
    
            for(var i = 0; i < l; i++) {
                images[i].addEventListener("click", function(i) {
                    var currentImg = this;
                    const parentItem = currentImg.parentElement, screenItem = document.createElement('div');
                    screenItem.id = "gg-screen";
                    container.prepend(screenItem);
                    if (parentItem.hasAttribute('data-theme')) screenItem.setAttribute("data-theme", "dark");
                    var route = currentImg.src;
                    root.style.overflow = 'hidden';
                    screenItem.innerHTML = '<div class="gg-image"></div><div class="gg-close gg-btn">×</div><div class="gg-next gg-btn">→</div><div class="gg-prev gg-btn">←</div>';
                    const first = images[0].src, last = images[l-1].src;
                    const imgItem = document.querySelector(".gg-image"), prevBtn = document.querySelector(".gg-prev"), nextBtn = document.querySelector(".gg-next"), close = document.querySelector(".gg-close");
                    imgItem.innerHTML = '<img src="' + route + '">';
    
                    if (l > 1) {
                    if (route == first) {
                        prevBtn.hidden = true;
                        var prevImg = false;
                        var nextImg = currentImg.nextElementSibling;
                    }
                    else if (route == last) {
                        nextBtn.hidden = true;
                        var nextImg = false;
                        var prevImg = currentImg.previousElementSibling;
                    }
                    else {
                        var prevImg = currentImg.previousElementSibling;
                        var nextImg = currentImg.nextElementSibling;
                    }
                    }
                    else {
                    prevBtn.hidden = true;
                    nextBtn.hidden = true;
                    }
    
                    screenItem.addEventListener("click", function(e) {
                    if (e.target == this || e.target == close) hide();
                    });
    
                    root.addEventListener("keydown", function(e) {
                    if (e.keyCode == 37 || e.keyCode == 38) prev();
                    if (e.keyCode == 39 || e.keyCode == 40) next();
                    if (e.keyCode == 27 ) hide();
                    });
    
                    prevBtn.addEventListener("click", prev);
                    nextBtn.addEventListener("click", next);
    
                    function prev() {
                        prevImg = currentImg.previousElementSibling;
                        imgItem.innerHTML = '<img src="' + prevImg.src + '">';
                        currentImg = currentImg.previousElementSibling;
                        var mainImg = document.querySelector(".gg-image > img").src;
                        nextBtn.hidden = false;
                        prevBtn.hidden = mainImg === first;
                    };
    
                    function next() {
                        nextImg = currentImg.nextElementSibling;
                        imgItem.innerHTML = '<img src="' + nextImg.src + '">';
                        currentImg = currentImg.nextElementSibling;
                        var mainImg = document.querySelector(".gg-image > img").src;
                        prevBtn.hidden = false;
                        nextBtn.hidden = mainImg === last;
                    };
    
                    function hide() {
                        root.style.overflow = 'auto';
                        screenItem.remove();
                    };
                });
            }
        </script>
    

rasterized photo gallery

Choose a photo
code:
        <div class="demos">
            <div class="demo__help">
            <a>Choose a photo</a>
            </div>
            <div class="demo__gallery">
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
                <div class="demo__placeholder"></div>
            </div>  
        </div>
        <style>
            .demos{display: flex; width: 90vw; height: 100vh; align-items: center; justify-content: center; flex-direction: column; background: linear-gradient(60deg, #5b5893, #2c2a49);}
            .demo__gallery {width: 688px; height: 460px; padding: 2px; flex-shrink: 0; background: #eee; perspective: 700px; border-radius: 5px;}
            .demo__placeholder { width: 110px; height: 110px; margin: 2px; float: left; background-color: lightslategrey; border-radius: 5px;}
            .demo__part {position: relative; float: left; width: 110px; height: 110px;  margin: 2px; transform: rotateY(180deg); transform-style: preserve-3d; transition: all 0.3s ease-in-out;}
            .demo__part:hover .demo__part-front {box-shadow: 0 0 10px black; transform: scale(0.96);}
            .demo__part:hover .demo__part-front:after {opacity: 0;}
            .demo__part-front, .demo__part-back {position: absolute; top: 0; left: 0; width: 100%; height: 100%;  overflow: hidden; -webkit-backface-visibility: hidden; backface-visibility: hidden; border-radius: 5px; 
                cursor: pointer;}
            .demo__part-front {background-color: lightslategrey; background-size: cover; background-position: center; transform: rotateX(0deg); transition: all 0.2s ease;}
            .demo__part-front:after {position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: black; content: ""; opacity: 0.5; transition: all 0.2s ease; }
            .demo__part-back {transform: rotateY(180deg) rotateX(0deg);}
            .demo__part-back-inner {width: 680px; height: 452px; background-image: url(../images/1.jpg); background-size: cover; background-position: center;-webkit-backface-visibility: hidden; 
                backface-visibility: hidden;}
            .demo__help { margin-bottom: 7px; font-size: 30px; font-family: "Yanone Kaffeesatz", sans-serif;  color: white;}
            .demo__help a {color: white;}
            .demo__help a:hover {color: #e39999;}
            .demo__part-1-1 .demo__part-back-inner {transform: translate(0px, 0px);}
            .demo__part-1-2 .demo__part-back-inner {transform: translate(-114px, 0px);}
            .demo__part-1-3 .demo__part-back-inner {transform: translate(-228px, 0px);}
            .demo__part-1-4 .demo__part-back-inner {transform: translate(-342px, 0px);}
            .demo__part-1-5 .demo__part-back-inner {transform: translate(-456px, 0px);}
            .demo__part-1-6 .demo__part-back-inner {transform: translate(-570px, 0px);}
            .demo__part-2-1 .demo__part-back-inner {transform: translate(0px, -114px);}
            .demo__part-2-2 .demo__part-back-inner {transform: translate(-114px, -114px);}
            .demo__part-2-3 .demo__part-back-inner {transform: translate(-228px, -114px);}
            .demo__part-2-4 .demo__part-back-inner {transform: translate(-342px, -114px);}
            .demo__part-2-5 .demo__part-back-inner {transform: translate(-456px, -114px);}
            .demo__part-2-6 .demo__part-back-inner {transform: translate(-570px, -114px);}
            .demo__part-3-1 .demo__part-back-inner {transform: translate(0px, -228px);}
            .demo__part-3-2 .demo__part-back-inner {transform: translate(-114px, -228px);}
            .demo__part-3-3 .demo__part-back-inner {transform: translate(-228px, -228px);}
            .demo__part-3-4 .demo__part-back-inner {transform: translate(-342px, -228px);}
            .demo__part-3-5 .demo__part-back-inner {transform: translate(-456px, -228px);}
            .demo__part-3-6 .demo__part-back-inner {transform: translate(-570px, -228px);}
            .demo__part-4-1 .demo__part-back-inner {transform: translate(0px, -342px);}
            .demo__part-4-2 .demo__part-back-inner {transform: translate(-114px, -342px);}
            .demo__part-4-3 .demo__part-back-inner {transform: translate(-228px, -342px);}
            .demo__part-4-4 .demo__part-back-inner {transform: translate(-342px, -342px);}
            .demo__part-4-5 .demo__part-back-inner {transform: translate(-456px, -342px);}
            .demo__part-4-6 .demo__part-back-inner {transform: translate(-570px, -342px);}
            .show-front {transform: none;}
        </style>
        <script>
            "use strict";
            $(document).ready(function() {
    
            var rows = 4; //change this also in css
            var cols = 6; //change this also in css
            var staggerTime = 150;
    
            var urls = [
                "../images/1.jpg",
                "../images/2.jpg",
                "../images/3.jpg",
                "../images/4.jpg",
                "../images/5.jpg",
                "../images/6.jpg",
                "../images/7.jpg",
                "../images/8.jpg",
                "../images/9.jpg",
                "../images/10.jpg",
                "../images/11.jpg",
                "../images/12.jpg",
                "../images/13a.jpg",
                "../images/14a.jpg",
                "../images/8a.jpg",
                "../images/9a.jpg",
                "../images/17.jpg",
                "../images/18.jpg",
                "../images/19.jpg",
                "../images/20.jpg",
                "../images/21.jpg",
                "../images/22.jpg",
                "../images/23.jpg",
                "../images/24.jpg",
            ];
    
            var $gallery = $(".demo__gallery");
            var $help = $(".demo__help");
            var partsArray = [];
            var reqAnimFr = (function() {
                return window.requestAnimationFrame || function(cb) {
                setTimeout(cb, 1000 / 60);
                }
            })();
            
            $gallery.html('');
            for (let row = 1; row <= rows; row++) {
                partsArray[row - 1] = [];
                for (let col = 1; col <= cols; col++) {
                $gallery.append(`<div class="show-front demo__part demo__part-${row}-${col}" row="${row}" col="${col}"><div class="demo__part-back"><div class="demo__part-back-inner"></div></div><
                div class="demo__part-front"></div></div>`);
                partsArray[row - 1][col - 1] = new Part();
                }
            }
            
            var $parts = $(".demo__part");
            var $image = $(".demo__part-back-inner");
            var help = true;
    
            for (let i = 0; i < $parts.length; i++) {
                $parts.find(".demo__part-front").eq(i).css("background-image", `url(${urls[i]})`);
            }
    
            $gallery.on("click", ".demo__part-front", function() {
                $image.css("background-image", $(this).css("background-image"));
                if (help) {
                    $help.html("Click any of the tiles to get back");
                    help = false;
                }
    
                let row = +$(this).closest(".demo__part").attr("row");
                let col = +$(this).closest(".demo__part").attr("col");
                waveChange(row, col);
            });
    
            $gallery.on("click", ".demo__part-back", function() {
                if (!isShowingBack()) return;
                for (let row = 1; row <= rows; row++) {
                    for (let col = 1; col <= cols; col++) {
                    partsArray[row - 1][col - 1].showing = "front";
                    }
                }
                }, staggerTime + $parts.length * staggerTime / 10);
                showFront(0, $parts.length);
            });
            
            function showFront(i, maxI) {
                if (i >= maxI) return;
                $parts.eq(i).addClass("show-front");
                reqAnimFr(function() {
                showFront(i + 1);
                });
            }
    
            function isShowingBack() {
                return partsArray[0][0].showing == "back" && partsArray[0][cols - 1].showing == "back" && partsArray[rows - 1][0].showing == "back" && partsArray[rows - 1][cols - 1].showing == "back";
            }
    
            function Part() {
                this.showing = "front";
            }
    
            function waveChange(rowN, colN) {
                if (rowN > rows || colN > cols || rowN <= 0 || colN <= 0) return;
                if (partsArray[rowN - 1][colN - 1].showing == "back") return;
                $(".demo__part-" + rowN + "-" + colN).removeClass("show-front");
                partsArray[rowN - 1][colN - 1].showing = "back";
                setTimeout(function() {
                waveChange(rowN + 1, colN);
                waveChange(rowN - 1, colN);
                waveChange(rowN, colN + 1);
                waveChange(rowN, colN - 1);
                }, staggerTime);
            }
            });
        </script>
    

photo gallery with full-screen jumping

code:
        <div class="gallery_X">
            <div class="img-w">
                <img src="../images/1a.jpg" alt="" />
            </div>
                <div class="img-w"><img src="../images/9a.jpg" alt="" /></div>
                <div class="img-w"><img src="../images/2a.jpg" alt="" /></div>
                <div class="img-w"><img src="../images/3a.jpg" alt="" /></div>
                <div class="img-w"><img src="../images/4a.jpg" alt="" /></div>
                <div class="img-w"><img src="../images/5a.jpg" alt="" /></div>
                <div class="img-w"><img src="../images/6a.jpg" alt="" /></div>
                <div class="img-w"><img src="../images/7a.jpg" alt="" /></div>
                <div class="img-w"><img src="../images/8a.jpg"alt="" /></div>
        </div>
        <style>
            .gallery_X {width: 600px; margin: auto; border-radius: 3px; overflow: hidden;}
            .img-c {width: 200px; height: 200px; float: left; position: relative; overflow: hidden;}
            .img-w { position: absolute; width: 100%; height: 100%; background-size: cover; background-position: center; cursor: pointer; transition: transform ease-in-out 300ms;}
            .img-w img {display: none;}
            .img-c {transition: width ease 400ms, height ease 350ms, left cubic-bezier(0.4, 0, 0.2, 1) 420ms, top cubic-bezier(0.4, 0, 0.2, 1) 420ms;}
            .img-c:hover .img-w {transform: scale(1.08); transition: transform cubic-bezier(0.4, 0, 0.2, 1) 450ms;}
            .img-c.active { width: 100% !important; height: 100% !important; position: absolute; z-index: 2; }
            .img-c.postactive { position: absolute; z-index: 2; pointer-events: none;}
            .img-c.active.positioned {left: 0 !important; top: 100 !important; transition-delay: 50ms;}
        </style>
        <script>
            $(function() {
                $(".img-w").each(function() {
                    $(this).wrap("<div class='img-c'></div>")
                    let imgSrc = $(this).find("img").attr("src");
                    $(this).css('background-image', 'url(' + imgSrc + ')');
                })
                            
                $(".img-c").click(function() {
                    let w = $(this).outerWidth()
                    let h = $(this).outerHeight()
                    let x = $(this).offset().left
                    let y = $(this).offset().top
                                    
                    $(".active").not($(this)).remove()
                    let copy = $(this).clone();
                    copy.insertAfter($(this)).height(h).width(w).delay(500).addClass("active")
                    $(".active").css('top', y - 8);
                    $(".active").css('left', x - 8);
                    
                    setTimeout(function() {
                    copy.addClass("positioned")
                }, 0)
                    
                }) 
            })

            $(document).on("click", ".img-c.active", function() {
                let copy = $(this)
                copy.removeClass("positioned active").addClass("postactive")
                setTimeout(function() {
                    copy.remove();
                }, 500)
            })
        </script>
    


thumbnails

top

create thumbnail

car
code:
        <style>
            .thumb img{border: 0.1vw; border-radius: 0.1vw; padding: 0.1vw; width: 10vw;}
            .thumb img:not(#tech, .container img, .slider label, .slider img, .basket img):
            hover{box-shadow: 0 0 0.2vw 0.1vw red;}
        </style>   
        <a target="_blank" href="../images/car2.jpg">
            <img class="thumb" src="../images/car2.jpg" alt="car"/>    
        </a>
    

the technique

bath
code:
        <img id="tech" src="../images/3.jpg" alt="bath" width="200" >
        <style>
            #tech{float:left; border: 0.2vw dashed blue;}
            #tech:hover{border:0.4vw solid green; box-shadow: 0vw 0.4vw 0.5px blue;}
        <style>
    

photo stack

code:
        <div class="container">
            <img src="../images/1.jpg">
            <img src="../images/1.jpg">
            <img src="../images/1.jpg">
            <img src="../images/1.jpg">
        </div>
        <style>
            .container {position: relative; width: 20vw; height: 12vw; margin-top: 5vw; background: rgba(0, 0, 0, 0); transform: 
                rotate(-30deg) skew(25deg) scale(0.8); transition: 0.5s;}
            .container img {position: absolute; width: 100%; transition: 0.5s;}
            .container:hover img:nth-child(4) {transform: translate(16vw, -16vw); opacity: 1;}
            .container:hover img:nth-child(3) {transform: translate(12vw, -12vw); opacity: 0.8;}
            .container:hover img:nth-child(2) {transform: translate(8vw, -8vw); opacity: 0.6;}
            .container:hover img:nth-child(1) {transform: translate(4vw, -4vw); opacity: 0.4;}
        </style>   
    

slider with thumbnails

code:
        <div class="boxes">
            <div class="slider">
                <input checked="checked" id="id1" name="ani" type="radio"> 
                <label for="id1"><img src="../images/1.jpg" width="60"></label> 
                <img src="../images/1.jpg">

                <input id="id2" name="ani" type="radio"> 
                <label for="id2"><img src="../images/2.jpg" width="60"></label> 
                <img src="../images/2.jpg"> 
                    
                <input id="id3" name="ani" type="radio"> 
                <label for="id3"><img src="../images//3.jpg" width="60"></label> 
                <img src="../images/3.jpg"> 
                
                <input id="id4" name="ani" type="radio"> 
                <label for="id4"><img src="../images/4.jpg" width="60"></label> 
                <img src="../images/4.jpg"> 
                
                <input id="id5" name="ani" type="radio"> 
                <label for="id5"><img src="../images/5.jpg" width="60"></label> 
                <img src="../images/5.jpg">
            </div>
        </div>
        <style>
            .boxes{display: grid;place-items: center; min-height: 40vw;}
            .slider1 {width: 30vw; height: 20vw;position: relative; padding-top: 25vw; margin: 1vw auto;}
            .slider1>img {position: absolute; left: 0; top: 0; transition: all 0.5s; width: 30vw; height: 25vw;}
            .slider1 input[name='ani'] {display: none;}
            .slider1 label { margin: 1vw 0 0 1vw; border: .3vw solid #999; float: left; cursor: pointer; transition: all 0.5s; opacity: 0.6; }
            .slider1 label img {display: block;}
            .slider1 input[name='ani']:checked+label {border-color: #666; opacity: 1;}
            .slider1 input[name='ani']~img { opacity: 0; transform: scale(1.1);}
            .slider1 input[name='ani']:checked+label+img {opacity: 1;transform: scale(1);}
        </style>   
    

filterable thumbnail layout

total photos: 12
  1. lake in the evening

  2. living on the beach

  3. ready for a refreshing shower

  4. ready for a sea trip

  5. relaxing on the beach

  6. evening meal at the local restaurant

  7. returning to the beach after the sea trip

  8. scenery in Shanghai - 2018

  9. Shanghai's tallest building - 2018

  10. the Huangpu river in Shanghai - 2018

  11. near the market in Changning district

  12. flooding in Shanghai in the summer of 2018

code:
        <section class="gallery">
            <div class="basket">
                <div class="toolbar">
                    <div class="search-wrapper">
                        <input type="search" placeholder="Search for photos">
                        <div class="counter">total photos: <span>12</span></div>
                    </div>
                    <ul class="view-options">
                        <li class="zoom"><input type="range" min="180" max="380" value="280"></li>
                        <li class="show-grid active"><button disabled><img src="../images/grid-view.svg" 
                        alt="grid view"></button></li>
                        <li class="show-list"><button><img src="../images/list-view.svg" alt="list view">
                        </button></li>
                    </ul>
                </div>
                <ol class="image-list grid-view">
                    <li>
                        <figure><img src="../images/1.jpg" alt=""/><figcaption><p>lake in the evening</p>
                        </figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/2.jpg" alt=""/><figcaption><p>living on the beach</p>
                        </figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/3.jpg" alt=""/><figcaption><p>ready for a refreshing shower
                        </p></figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/4.jpg" alt=""><figcaption><p>ready for a sea trip</p>
                        </figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/5.jpg" alt=""><figcaption><p>relaxing on the beach</p>
                        </figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/7.jpg" alt=""><figcaption><p>evening meal at the local 
                        restaurant</p></figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/8.jpg" alt=""><figcaption><p>returning to the beach after 
                        the sea trip</p></figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/2018-Sh-02.jpg" alt=""><figcaption><p>scenery in Shanghai
                            - 2018</p></figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/2018-Sh-03.jpg" alt=""><figcaption><p>Shanghai's tallest 
                        building - 2018</p></figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/2018-Sh-04.jpg" alt=""><figcaption><p>the Huangpu river in 
                        Shanghai - 2018</p></figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/2018-Sh-05.jpg" alt=""><figcaption><p>near the market in 
                        Changning districtlt;/p></figcaption></figure>
                    </li>
                    <li>
                        <figure><img src="../images/2018-Sh-06.jpg" alt=""><figcaption><p>flooding in Shanghai 
                        in the summer of 2018</p></figcaption></figure>
                    </li>
                </ol>
            </div>
        </section>   
        <style>
                :root {--black: #1a1a1a; --white: #fff; --gray: #ccc; --darkgreen: #18846C; 
                    --lightbrown: antiquewhite; --darkblack: rgba(0,0,0,0.8); --minRangeValue: 280px}
                button {cursor: pointer; background: skyblue;}
                ol img {display: block;  max-width: 100%; height: auto; }
                ol, ul {list-style: none;}
                a:not(.grid_B a, h2~a) {color: inherit;}
                .gallery {padding: 0 2vw;}
                .basket {max-width: 100vw; margin: 0 auto;}
                .d-none {display: none;}

                /* TOOLBAR */
                .toolbar {display: flex;justify-content: space-between;  align-items: center;}
                .toolbar .search-wrapper {position: relative;}
                .toolbar input[type="search"] {font-size: 1vw; border: none; border-bottom: .1vw solid; 
                    padding-bottom: .3vw; background: var(--lightbrown);}
                .toolbar ::placeholder {color: var(--gray);}
                .toolbar .counter {position: relative; left: 0; top: calc(100% + .5vw); font-size: 1.1vw; 
                    color: var(--black); }
                .view-options {display: flex;align-items: center;}
                .view-options li:not(:last-child) {margin-right: 1.2vw;}
                .view-options button {padding: .2vw; border: .3vw solid transparent;}
                .view-options .active button {border-color: var(--darkgreen);}

                /* IMAGE LIST */
                .image-list {margin: 1vw 0;}
                .image-list li {background: var(--lightbrown); color: var(--darkblack);}
                .image-list p:first-child {font-weight: bold; font-size: 1.5vw;}
                .image-list p:last-child {margin-top: 1.5vw;}

                /* GRID VIEW */
                .grid-view {display: grid; grid-gap: 1vw; grid-template-columns: repeat(auto-fit, 
                    minmax(var(--minRangeValue), 1fr));}
                .grid-view figcaption {padding: 1vw;}

                /* LIST VIEW */
                .list-view li + li { margin-top: 1.5vw; }
                .list-view figure {display: grid; grid-gap: 1.5vw; grid-template-columns: 15vw 1fr; 
                    align-items: center; }

                /* Media Queries */
                @media screen and (max-width: 900px) {
                .toolbar input[type="range"] {display: none;}
                }

                @media screen and (max-width: 700px) {
                    .grid-view li {text-align: center; padding: 0.5vw;}
                    .grid-view figcaption {padding: 0.5vw 0 0; }
                }
        </style>
        <script>
            // VARIABLES
            const rangeInput = document.querySelector('input[type = "range"]');
            const imageList = document.querySelector(".image-list");
            const searchInput = document.querySelector('input[type="search"]');
            const btns = document.querySelectorAll(".view-options button");
            const photosCounter = document.querySelector(".toolbar .counter span");
            const imageListItems = document.querySelectorAll(".image-list li");
            const captions = document.querySelectorAll(".image-list figcaption p:first-child");
            const myArray = [];
            let counter = 1;
            const active = "active";
            const listView = "list-view";
            const gridView = "grid-view";
            const dNone = "d-none";

            // SET VIEW
            for (const btn of btns) {
                btn.addEventListener("click", function() {
                    const parent = this.parentElement;
                    document.querySelector(".view-options .active").classList.remove(active);
                    parent.classList.add(active);
                    this.disabled = true;
                    document.querySelector('.view-options [class^="show-"]:not(.active) button').disabled = false;

                    if (parent.classList.contains("show-list")) {
                        parent.previousElementSibling.previousElementSibling.classList.add(dNone);
                        imageList.classList.remove(gridView);
                        imageList.classList.add(listView);
                    } else {
                        parent.previousElementSibling.classList.remove(dNone);
                        imageList.classList.remove(listView);
                        imageList.classList.add(gridView);
                    }
                });
            }

            // SET THUMBNAIL VIEW - CHANGE CSS VARIABLE
            rangeInput.addEventListener("input", function() {
                document.documentElement.style.setProperty("--minRangeValue",`${this.value}px`);
            });

            // SEARCH FUNCTIONALITY
            for (const caption of captions) {
                myArray.push({
                    id: counter++,
                    text: caption.textContent
                });
            }
            searchInput.addEventListener("keyup", keyupHandler);

            function keyupHandler() {
                for (const item of imageListItems) {
                    item.classList.add(dNone);
                }
                const text = this.value;
                const filteredArray = myArray.filter(el => el.text.includes(text));
                if (filteredArray.length > 0) {
                    for (const el of filteredArray) {
                        document.querySelector(`.image-list li:nth-child(${el.id})`).classList.remove(dNone);
                    }
                }
            photosCounter.textContent = filteredArray.length;
            }
        </script>